package org.example.contracts;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.fisco.bcos.sdk.abi.FunctionReturnDecoder;
import org.fisco.bcos.sdk.abi.TypeReference;
import org.fisco.bcos.sdk.abi.datatypes.Function;
import org.fisco.bcos.sdk.abi.datatypes.Type;
import org.fisco.bcos.sdk.abi.datatypes.Utf8String;
import org.fisco.bcos.sdk.abi.datatypes.generated.Uint256;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple1;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple2;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.contract.Contract;
import org.fisco.bcos.sdk.crypto.CryptoSuite;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.model.CryptoType;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.model.callback.TransactionCallback;
import org.fisco.bcos.sdk.transaction.model.exception.ContractException;

@SuppressWarnings("unchecked")
public class Structs extends Contract {
    public static final String[] BINARY_ARRAY = {"60806040526001805534801561001457600080fd5b50610840806100246000396000f300608060405260043610610078576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306ead22e1461007d578063453e056a1461012a57806361b8ce8c146101935780636af83845146101be578063ed2e5a97146101eb578063f745630f14610291575b600080fd5b34801561008957600080fd5b506100a860048036038101908080359060200190929190505050610304565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156100ee5780820151818401526020810190506100d3565b50505050905090810190601f16801561011b5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561013657600080fd5b50610191600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506103cf565b005b34801561019f57600080fd5b506101a861045e565b6040518082815260200191505060405180910390f35b3480156101ca57600080fd5b506101e960048036038101908080359060200190929190505050610464565b005b3480156101f757600080fd5b50610216600480360381019080803590602001909291905050506104ad565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561025657808201518184015260208101905061023b565b50505050905090810190601f1680156102835780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561029d57600080fd5b5061030260048036038101908080359060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610580565b005b60008181548110151561031357fe5b9060005260206000209060020201600091509050806000015490806001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103c55780601f1061039a576101008083540402835291602001916103c5565b820191906000526020600020905b8154815290600101906020018083116103a857829003601f168201915b5050505050905082565b6103d761068d565b60408051908101604052806001548152602001838152509050600081908060018154018082558091505090600182039060005260206000209060020201600090919290919091506000820151816000015560208201518160010190805190602001906104449291906106a7565b505050506001600081548092919060010191905055505050565b60015481565b600061046f826105c7565b905060008181548110151561048057fe5b90600052602060002090600202016000808201600090556001820160006104a79190610727565b50505050565b606060006104ba836105c7565b90506000818154811015156104cb57fe5b90600052602060002090600202016001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105705780601f1061054557610100808354040283529160200191610570565b820191906000526020600020905b81548152906001019060200180831161055357829003601f168201915b5050505050915081915050919050565b600061058b836105c7565b90508160008281548110151561059d57fe5b906000526020600020906002020160010190805190602001906105c192919061076f565b50505050565b600080600090505b60008054905081101561061957826000828154811015156105ec57fe5b906000526020600020906002020160000154141561060c57809150610687565b80806001019150506105cf565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f55736572206e6f7420666f756e6400000000000000000000000000000000000081525060200191505060405180910390fd5b50919050565b604080519081016040528060008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106106e857805160ff1916838001178555610716565b82800160010185558215610716579182015b828111156107155782518255916020019190600101906106fa565b5b50905061072391906107ef565b5090565b50805460018160011615610100020316600290046000825580601f1061074d575061076c565b601f01602090049060005260206000209081019061076b91906107ef565b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107b057805160ff19168380011785556107de565b828001600101855582156107de579182015b828111156107dd5782518255916020019190600101906107c2565b5b5090506107eb91906107ef565b5090565b61081191905b8082111561080d5760008160009055506001016107f5565b5090565b905600a165627a7a723058205aef331abe4d23296c03c64c8492a59b83ad6af1bca8b27a05e186a1f3b7d5d40029"};

    public static final String BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", BINARY_ARRAY);

    public static final String[] SM_BINARY_ARRAY = {"60806040526001805534801561001457600080fd5b50610840806100246000396000f300608060405260043610610078576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306ead22e1461007d578063453e056a1461012a57806361b8ce8c146101935780636af83845146101be578063ed2e5a97146101eb578063f745630f14610291575b600080fd5b34801561008957600080fd5b506100a860048036038101908080359060200190929190505050610304565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156100ee5780820151818401526020810190506100d3565b50505050905090810190601f16801561011b5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b34801561013657600080fd5b50610191600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506103cf565b005b34801561019f57600080fd5b506101a861045e565b6040518082815260200191505060405180910390f35b3480156101ca57600080fd5b506101e960048036038101908080359060200190929190505050610464565b005b3480156101f757600080fd5b50610216600480360381019080803590602001909291905050506104ad565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561025657808201518184015260208101905061023b565b50505050905090810190601f1680156102835780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561029d57600080fd5b5061030260048036038101908080359060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610580565b005b60008181548110151561031357fe5b9060005260206000209060020201600091509050806000015490806001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103c55780601f1061039a576101008083540402835291602001916103c5565b820191906000526020600020905b8154815290600101906020018083116103a857829003601f168201915b5050505050905082565b6103d761068d565b60408051908101604052806001548152602001838152509050600081908060018154018082558091505090600182039060005260206000209060020201600090919290919091506000820151816000015560208201518160010190805190602001906104449291906106a7565b505050506001600081548092919060010191905055505050565b60015481565b600061046f826105c7565b905060008181548110151561048057fe5b90600052602060002090600202016000808201600090556001820160006104a79190610727565b50505050565b606060006104ba836105c7565b90506000818154811015156104cb57fe5b90600052602060002090600202016001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105705780601f1061054557610100808354040283529160200191610570565b820191906000526020600020905b81548152906001019060200180831161055357829003601f168201915b5050505050915081915050919050565b600061058b836105c7565b90508160008281548110151561059d57fe5b906000526020600020906002020160010190805190602001906105c192919061076f565b50505050565b600080600090505b60008054905081101561061957826000828154811015156105ec57fe5b906000526020600020906002020160000154141561060c57809150610687565b80806001019150506105cf565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f55736572206e6f7420666f756e6400000000000000000000000000000000000081525060200191505060405180910390fd5b50919050565b604080519081016040528060008152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106106e857805160ff1916838001178555610716565b82800160010185558215610716579182015b828111156107155782518255916020019190600101906106fa565b5b50905061072391906107ef565b5090565b50805460018160011615610100020316600290046000825580601f1061074d575061076c565b601f01602090049060005260206000209081019061076b91906107ef565b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107b057805160ff19168380011785556107de565b828001600101855582156107de579182015b828111156107dd5782518255916020019190600101906107c2565b5b5090506107eb91906107ef565b5090565b61081191905b8082111561080d5760008160009055506001016107f5565b5090565b905600a165627a7a723058205aef331abe4d23296c03c64c8492a59b83ad6af1bca8b27a05e186a1f3b7d5d40029"};

    public static final String SM_BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", SM_BINARY_ARRAY);

    public static final String[] ABI_ARRAY = {"[{\"methodSignatureAsString\":\"students(uint256)\",\"name\":\"students\",\"type\":\"function\",\"constant\":true,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"view\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"\",\"indexed\":false,\"components\":[],\"dynamic\":false,\"typeAsString\":\"uint256\"}],\"outputs\":[{\"name\":\"id\",\"type\":\"uint256\",\"internalType\":\"\",\"indexed\":false,\"components\":[],\"dynamic\":false,\"typeAsString\":\"uint256\"},{\"name\":\"name\",\"type\":\"string\",\"internalType\":\"\",\"indexed\":false,\"components\":[],\"dynamic\":true,\"typeAsString\":\"string\"}]},{\"methodSignatureAsString\":\"addStudent(string)\",\"name\":\"addStudent\",\"type\":\"function\",\"constant\":false,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"nonpayable\",\"inputs\":[{\"name\":\"name\",\"type\":\"string\",\"internalType\":\"\",\"indexed\":false,\"components\":[],\"dynamic\":true,\"typeAsString\":\"string\"}],\"outputs\":[]},{\"methodSignatureAsString\":\"nextId()\",\"name\":\"nextId\",\"type\":\"function\",\"constant\":true,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"view\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"\",\"indexed\":false,\"components\":[],\"dynamic\":false,\"typeAsString\":\"uint256\"}]},{\"methodSignatureAsString\":\"removeStudent(uint256)\",\"name\":\"removeStudent\",\"type\":\"function\",\"constant\":false,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"nonpayable\",\"inputs\":[{\"name\":\"id_\",\"type\":\"uint256\",\"internalType\":\"\",\"indexed\":false,\"components\":[],\"dynamic\":false,\"typeAsString\":\"uint256\"}],\"outputs\":[]},{\"methodSignatureAsString\":\"read(uint256)\",\"name\":\"read\",\"type\":\"function\",\"constant\":true,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"view\",\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\",\"internalType\":\"\",\"indexed\":false,\"components\":[],\"dynamic\":false,\"typeAsString\":\"uint256\"}],\"outputs\":[{\"name\":\"name\",\"type\":\"string\",\"internalType\":\"\",\"indexed\":false,\"components\":[],\"dynamic\":true,\"typeAsString\":\"string\"}]},{\"methodSignatureAsString\":\"update(uint256,string)\",\"name\":\"update\",\"type\":\"function\",\"constant\":false,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"nonpayable\",\"inputs\":[{\"name\":\"id_\",\"type\":\"uint256\",\"internalType\":\"\",\"indexed\":false,\"components\":[],\"dynamic\":false,\"typeAsString\":\"uint256\"},{\"name\":\"name_\",\"type\":\"string\",\"internalType\":\"\",\"indexed\":false,\"components\":[],\"dynamic\":true,\"typeAsString\":\"string\"}],\"outputs\":[]}]"};

    public static final String ABI = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", ABI_ARRAY);

    public static final String FUNC_STUDENTS = "students";

    public static final String FUNC_ADDSTUDENT = "addStudent";

    public static final String FUNC_NEXTID = "nextId";

    public static final String FUNC_REMOVESTUDENT = "removeStudent";

    public static final String FUNC_READ = "read";

    public static final String FUNC_UPDATE = "update";

    protected Structs(String contractAddress, Client client, CryptoKeyPair credential) {
        super(getBinary(client.getCryptoSuite()), contractAddress, client, credential);
    }

    public static String getBinary(CryptoSuite cryptoSuite) {
        return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BINARY : SM_BINARY);
    }

    public Tuple2<BigInteger, String> students(BigInteger param0) throws ContractException {
        final Function function = new Function(FUNC_STUDENTS, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(param0)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}, new TypeReference<Utf8String>() {}));
        List<Type> results = executeCallWithMultipleValueReturn(function);
        return new Tuple2<BigInteger, String>(
                (BigInteger) results.get(0).getValue(), 
                (String) results.get(1).getValue());
    }

    public TransactionReceipt addStudent(String name) {
        final Function function = new Function(
                FUNC_ADDSTUDENT, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(name)), 
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public byte[] addStudent(String name, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_ADDSTUDENT, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(name)), 
                Collections.<TypeReference<?>>emptyList());
        return asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForAddStudent(String name) {
        final Function function = new Function(
                FUNC_ADDSTUDENT, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(name)), 
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple1<String> getAddStudentInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_ADDSTUDENT, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple1<String>(

                (String) results.get(0).getValue()
                );
    }

    public BigInteger nextId() throws ContractException {
        final Function function = new Function(FUNC_NEXTID, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        return executeCallWithSingleValueReturn(function, BigInteger.class);
    }

    public TransactionReceipt removeStudent(BigInteger id_) {
        final Function function = new Function(
                FUNC_REMOVESTUDENT, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(id_)), 
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public byte[] removeStudent(BigInteger id_, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_REMOVESTUDENT, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(id_)), 
                Collections.<TypeReference<?>>emptyList());
        return asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForRemoveStudent(BigInteger id_) {
        final Function function = new Function(
                FUNC_REMOVESTUDENT, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(id_)), 
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple1<BigInteger> getRemoveStudentInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_REMOVESTUDENT, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple1<BigInteger>(

                (BigInteger) results.get(0).getValue()
                );
    }

    public String read(BigInteger id) throws ContractException {
        final Function function = new Function(FUNC_READ, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(id)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}));
        return executeCallWithSingleValueReturn(function, String.class);
    }

    public TransactionReceipt update(BigInteger id_, String name_) {
        final Function function = new Function(
                FUNC_UPDATE, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(id_), 
                new org.fisco.bcos.sdk.abi.datatypes.Utf8String(name_)), 
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public byte[] update(BigInteger id_, String name_, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_UPDATE, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(id_), 
                new org.fisco.bcos.sdk.abi.datatypes.Utf8String(name_)), 
                Collections.<TypeReference<?>>emptyList());
        return asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForUpdate(BigInteger id_, String name_) {
        final Function function = new Function(
                FUNC_UPDATE, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(id_), 
                new org.fisco.bcos.sdk.abi.datatypes.Utf8String(name_)), 
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple2<BigInteger, String> getUpdateInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_UPDATE, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}, new TypeReference<Utf8String>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple2<BigInteger, String>(

                (BigInteger) results.get(0).getValue(), 
                (String) results.get(1).getValue()
                );
    }

    public static Structs load(String contractAddress, Client client, CryptoKeyPair credential) {
        return new Structs(contractAddress, client, credential);
    }

    public static Structs deploy(Client client, CryptoKeyPair credential) throws ContractException {
        return deploy(Structs.class, client, credential, getBinary(client.getCryptoSuite()), "");
    }
}
